home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / texts / mpindx50.lha / MPIndex50Src.lha / sh / MakeMPIndex.c next >
C/C++ Source or Header  |  1996-05-10  |  15KB  |  777 lines

  1. // MPIndex - AmigaGuide Indexing program
  2. // Copyright (C) © 1996 Mark John Paddock
  3.  
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // any later version.
  8.  
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13.  
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. // mark@topic.demon.co.uk
  19. // mpaddock@cix.compulink.co.uk
  20.  
  21. // Change following line to #define MPINDEXPRINT 1 to allow printing (for debugging)
  22. #undef MPINDEXPRINT
  23.  
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <ctype.h>
  27. #include <stdlib.h>
  28. #include <proto/dos.h>
  29. #include <proto/exec.h>
  30. #include <exec/memory.h>
  31.  
  32. extern long __oslibversion=39;
  33.  
  34. extern long __stack = 16000;
  35.  
  36. struct IgnoreWord {
  37.     char *Word;
  38.     BOOL ReallyIgnore;
  39.     struct IgnoreWord *Left;
  40.     struct IgnoreWord *Right;
  41. };
  42.  
  43. struct IgnoreWord *TopIgnore;
  44.  
  45. const char Version[]="$VER: MakeMPIndex 5.0 (10.5.96)";
  46.  
  47. static int NodeCount = 0;
  48.  
  49. extern void *Chain = NULL;
  50. #define PUDDLE 64000
  51. #define THRESH 3000
  52.  
  53. struct RDArgs *rdargs = NULL;
  54.  
  55. APTR
  56. Mycalloc(ULONG size) {
  57.     APTR res;
  58.     res = AllocPooled(Chain,size);
  59.     if (res) {
  60.         return res;
  61.     }
  62.     DeletePool(Chain);
  63.     FreeArgs(rdargs);
  64.     printf("Out of memory\n");
  65.     exit(10);
  66. }
  67.  
  68. APTR
  69. Mystrdup(UBYTE *str) {
  70.     return strcpy(Mycalloc(strlen(str)+1),str);
  71. }
  72.  
  73. struct Link {
  74.     struct MyNode *MyNode;
  75.     struct Word *Word;
  76.     struct Link *NextNodeLink;
  77.     struct Link *NextWordLink;
  78.     int Count;
  79. };
  80.  
  81. struct MyNode {
  82.     char *Title;
  83.     char *Name;
  84.     struct MyNode *Left;
  85.     struct MyNode *Right;
  86.     struct Link *FirstLink;
  87.     int Count;
  88.     int Num;
  89.     int seq;
  90. };
  91.  
  92. static struct MyNode *TopNode = NULL;
  93.  
  94. struct Word {
  95.     char *Word;
  96.     struct Word *Left;
  97.     struct Word *Right;
  98.     struct Link *FirstLink;
  99.     int Count;
  100. };
  101.  
  102. static struct Word *TopWord = NULL;
  103. static int WordCount = 0;
  104.  
  105. struct Word *
  106. AddWord(char *p) {
  107.     struct Word *Word1;
  108.     int strres;
  109.     if (!TopWord) {
  110.         TopWord = Mycalloc(sizeof(struct Word));
  111.         TopWord->Word = Mystrdup(p);
  112.         return TopWord;
  113.     }
  114.     Word1 = TopWord;
  115.     while (1) {
  116.         strres = stricmp(Word1->Word,p);
  117.         if (!strres) {
  118.             return Word1;
  119.         }
  120.         if (strres > 0) {
  121.             if (!Word1->Left) {
  122.                 Word1->Left = Mycalloc(sizeof(struct Word));
  123.                 Word1->Left->Word = Mystrdup(p);
  124.                 return Word1->Left;
  125.             }
  126.             Word1 = Word1->Left;
  127.         }
  128.         else {
  129.             if (!Word1->Right) {
  130.                 Word1->Right = Mycalloc(sizeof(struct Word));
  131.                 Word1->Right->Word = Mystrdup(p);
  132.                 return Word1->Right;
  133.             }
  134.             Word1 = Word1->Right;
  135.         }
  136.     }
  137. }
  138.  
  139. static void
  140. LinkInWord(struct MyNode *MyNode,struct Word *Word,struct Link *Link1) {
  141.     struct Link *Link,*Link2;
  142.     Link = Word->FirstLink;
  143.     Link2 = NULL;
  144.     while (Link && 
  145.              (0 < stricmp(Link->MyNode->Title,MyNode->Title))) {
  146.         Link2 = Link;
  147.         Link = Link->NextWordLink;
  148.     }
  149.     if (Link) {
  150.         Link1->NextWordLink = Link;
  151.         if (Link2) {
  152.             Link2->NextWordLink = Link1;
  153.         }
  154.         else {
  155.             Word->FirstLink = Link1;
  156.         }
  157.     }
  158.     else {
  159.         if (Link2) {
  160.             Link2->NextWordLink = Link1;
  161.         }
  162.         else {
  163.             Link1->NextWordLink = Word->FirstLink;
  164.             Word->FirstLink = Link1;
  165.         }
  166.     }
  167. }
  168. static void
  169. LinkNodeWord(struct MyNode *MyNode,struct Word *Word) {
  170.     struct Link *Link,*Link1,*Link2;
  171.     Link2 = NULL;
  172.     Link = MyNode->FirstLink;
  173.     while (Link && (stricmp(Link->Word->Word,Word->Word) < 0)) {
  174.         Link2 = Link;
  175.         Link = Link->NextNodeLink;
  176.     }
  177.     if (Link) {
  178.         if (!stricmp(Link->Word->Word,Word->Word)) {
  179.             ++Link->Count;
  180.         }
  181.         else {
  182.             ++Word->Count;
  183.             ++MyNode->Count;
  184.             Link1 = Mycalloc(sizeof(struct Link));
  185.             Link1->MyNode = MyNode;
  186.             Link1->Word = Word;
  187.             Link1->Count = 1;
  188.             Link1->NextNodeLink = Link;
  189.             if (Link2) {
  190.                 Link2->NextNodeLink = Link1;
  191.             }
  192.             else {
  193.                 MyNode->FirstLink = Link1;
  194.             }
  195.             LinkInWord(MyNode,Word,Link1);
  196.         }
  197.     }
  198.     else {
  199.         ++Word->Count;
  200.         ++MyNode->Count;
  201.         Link1 = Mycalloc(sizeof(struct Link));
  202.         Link1->MyNode = MyNode;
  203.         Link1->Word = Word;
  204.         Link1->Count = 1;
  205.         if (Link2) {
  206.             Link2->NextNodeLink = Link1;
  207.         }
  208.         else {
  209.             Link1->NextNodeLink = MyNode->FirstLink;
  210.             MyNode->FirstLink = Link1;
  211.         }
  212.         LinkInWord(MyNode,Word,Link1);
  213.     }
  214. }
  215.  
  216. BOOL
  217. CheckIgnore(char *p) {
  218.     struct IgnoreWord *IgnoreWord;
  219.     int strres;
  220.  
  221.     IgnoreWord = TopIgnore;
  222.     if (!IgnoreWord) {
  223.         return TRUE;
  224.     }
  225.     while (1) {
  226.         strres = stricmp(IgnoreWord->Word,p);
  227.         if (!strres) {
  228.             return (BOOL)!IgnoreWord->ReallyIgnore;
  229.         }
  230.         if (strres > 0) {
  231.             if (!IgnoreWord->Left) {
  232.                 return TRUE;
  233.             }
  234.             IgnoreWord = IgnoreWord->Left;
  235.         }
  236.         else {
  237.             if (!IgnoreWord->Right) {
  238.                 return TRUE;
  239.             }
  240.             IgnoreWord = IgnoreWord->Right;
  241.         }
  242.     }
  243. }
  244.  
  245. static void
  246. AddWords(struct MyNode *MyNode,char *buffer) {
  247.     char tbuff[257];
  248.     struct Word *Word;
  249.     char *p,*p1,*p2;
  250.     int Done = 0;
  251.     strcpy(tbuff,buffer);
  252.     p = tbuff;
  253.     while (!Done) {
  254.         if ('@' == *p) {
  255.             ++p;
  256.             while (*p && (isalnum(*p) || ('_' == *p) || ('-' == *p))) {
  257.                 ++p;
  258.             }
  259.             if (!*p) {
  260.                 Done = 1;
  261.             }
  262.         }
  263.         else {
  264.             if (isalnum(*p)) {
  265.                 p1 = p;
  266.                 while (*p1 && (isalnum(*p1) || ('_' == *p) || ('-' == *p) || ('.' == *p))) {
  267.                     ++p1;
  268.                 }
  269.                 p2 = p1;
  270.                 --p2;
  271.                 while ('.' == *p2) {
  272.                     *p2 = 0;
  273.                     --p2;
  274.                 }
  275.                 if (*p1) {
  276.                     if ('\n' == *p1) {
  277.                         Done = 1;
  278.                     }
  279.                     *p1 = 0;
  280.                 }
  281.                 else {
  282.                     Done = 1;
  283.                 }
  284.                 if (CheckIgnore(p)) {
  285.                     Word = AddWord(p);
  286.                     LinkNodeWord(MyNode,Word);
  287.                 }
  288.                 p = p1;
  289.             }
  290.             else {
  291.                 if (!*p) {
  292.                     Done = 1;
  293.                 }
  294.             }
  295.         }
  296.         ++p;
  297.     }
  298. }
  299.  
  300. static void
  301. WriteNodes(struct MyNode *MyNode,FILE *fp) {
  302.     if (!MyNode) {
  303.         return;
  304.     }
  305.     if (MyNode->Left) {
  306.         WriteNodes(MyNode->Left,fp);
  307.     }
  308.     if (MyNode->Count) {
  309.         fprintf(fp,"%ld+%s\n",MyNode->seq,MyNode->Name);
  310.         fprintf(fp,"%s\n",MyNode->Title);
  311.     }
  312.     if (MyNode->Right) {
  313.         WriteNodes(MyNode->Right,fp);
  314.     }
  315. }
  316.  
  317. static void
  318. CountNodes(struct MyNode *MyNode) {
  319.     if (!MyNode) {
  320.         return;
  321.     }
  322.     if (MyNode->Left) {
  323.         CountNodes(MyNode->Left);
  324.     }
  325.     if (MyNode->Title) {
  326.         MyNode->Num = NodeCount;
  327.         ++NodeCount;
  328.     }
  329.     if (MyNode->Right) {
  330.         CountNodes(MyNode->Right);
  331.     }
  332. }
  333.  
  334. #ifdef MPINDEXPRINT
  335. static void
  336. PrintNode(struct MyNode *MyNode) {
  337.     struct Link *Link;
  338.     if (!MyNode) {
  339.         return;
  340.     }
  341.     if (MyNode->Left) {
  342.         PrintNode(MyNode->Left);
  343.     }
  344.     printf("%s - %s\t%d\n",MyNode->Name,MyNode->Title,MyNode->Count);
  345.     Link = MyNode->FirstLink;
  346.     while (Link) {
  347.         printf("\t%s\t%d\n",Link->Word->Word,Link->Count);
  348.         Link = Link->NextNodeLink;
  349.     }
  350.     if (MyNode->Right) {
  351.         PrintNode(MyNode->Right);
  352.     }
  353. }
  354. #endif
  355.  
  356. static void
  357. WriteWords(struct Word *Word,FILE *fp,ULONG max) {
  358.     struct Link *Link;
  359.     if (!Word) {
  360.         return;
  361.     }
  362.     if (Word->Left) {
  363.         WriteWords(Word->Left,fp,max);
  364.     }
  365.     if ((0 == max) || !(Word->Count > max)) {
  366.         if (Word->Count) {
  367.             fprintf(fp,"!%s\n",Word->Word);
  368.             Link = Word->FirstLink;
  369.             while (Link) {
  370.                 fprintf(fp,"%d\n",Link->MyNode->Num);
  371.                 Link = Link->NextWordLink;
  372.             }
  373.         }
  374.     }
  375.     if (Word->Right) {
  376.         WriteWords(Word->Right,fp,max);
  377.     }
  378. }
  379.  
  380. #ifdef MPINDEXPRINT
  381. static void
  382. PrintWord(struct Word *Word) {
  383.     struct Link *Link;
  384.     if (!Word) {
  385.         return;
  386.     }
  387.     if (Word->Left) {
  388.         PrintWord(Word->Left);
  389.     }
  390.     printf("Word - %s\t%d\n",Word->Word,Word->Count);
  391.     Link = Word->FirstLink;
  392.     while (Link) {
  393.         printf("\t%s\t%d\n",Link->MyNode->Title,Link->Count);
  394.         Link = Link->NextWordLink;
  395.     }
  396.     if (Word->Right) {
  397.         PrintWord(Word->Right);
  398.     }
  399. }
  400. #endif
  401.  
  402. static int InCurly = 0;
  403.  
  404. static void
  405. Strip(char *buffer) {
  406.  
  407.     char *p,*p1;
  408.     p = buffer;
  409.     p1 = buffer;
  410.     while (*p1) {
  411.         if (InCurly) {
  412.             while (*p1 && (*p1 != '}')) {
  413.                 ++p1;
  414.             }
  415.             if (*p1) {
  416.                 ++p1;
  417.                 InCurly = 0;
  418.             }
  419.         }
  420.         else {
  421.             if (('@' == *p1) && ('{' == p1[1])) {
  422.                 if ('"' == p1[2]) {
  423.                     ++p1;
  424.                     ++p1;
  425.                     ++p1;
  426.                     while (*p1 && (*p1 != '"')) {
  427.                         *p++ = *p1++;
  428.                     }
  429.                     InCurly = 1;
  430.                 }
  431.                 else {
  432.                     InCurly = 1;
  433.                 }
  434.             }
  435.             else {
  436.                 *p++ = *p1++;
  437.             }
  438.         }
  439.     }
  440.     *p = 0;
  441. }
  442.  
  443. void
  444. WriteFiles(char **files,FILE *fp) {
  445.     int i;
  446.     for (i=0; files[i]; ++i) {
  447.         fprintf(fp,"+%s\n",files[i]);
  448.     }
  449. }
  450.  
  451. static void
  452. AddNode(struct MyNode *MyNode) {
  453.     struct MyNode *Node1;
  454.     if (!TopNode) {
  455.         TopNode = MyNode;
  456.         return;
  457.     }
  458.     Node1 = TopNode;
  459.     while (1) {
  460.         if (stricmp(Node1->Name,MyNode->Name) > 0) {
  461.             if (!Node1->Left) {
  462.                 Node1->Left = MyNode;
  463.                 return;
  464.             }
  465.             else {
  466.                 Node1 = Node1->Left;
  467.             }
  468.         }
  469.         else {
  470.             if (!Node1->Right) {
  471.                 Node1->Right = MyNode;
  472.                 return;
  473.             }
  474.             else {
  475.                 Node1 = Node1->Right;
  476.             }
  477.         }
  478.     }
  479. }
  480.  
  481. static struct MyNode *
  482. FindNode(struct MyNode *MyNode, int i) {
  483.     struct MyNode *Node1;
  484.  
  485.     if (!MyNode) {
  486.         return NULL;
  487.     }
  488.     if (MyNode->Title) {
  489.         if (MyNode->Num == i) {
  490.             return MyNode;
  491.         }
  492.     }
  493.     if (MyNode->Left) {
  494.         if (Node1 = FindNode(MyNode->Left,i)) {
  495.             return Node1;
  496.         }
  497.     }
  498.     if (MyNode->Right) {
  499.         if (Node1 = FindNode(MyNode->Right,i)) {
  500.             return Node1;
  501.         }
  502.     }
  503. }
  504.  
  505. static void
  506. AddIgnore(char *p,BOOL ignore) {
  507.     struct IgnoreWord *Node,*Node1;
  508.     int strres;
  509.     // May not get used if duplicate
  510.     Node = Mycalloc(sizeof(struct IgnoreWord));
  511.     Node->Word = Mystrdup(p);
  512.     Node->ReallyIgnore = ignore;
  513.     if (!TopIgnore) {
  514.         TopIgnore = Node;
  515.         return;
  516.     }
  517.     Node1 = TopIgnore;
  518.     while (1) {
  519.         strres = stricmp(Node1->Word,Node->Word);
  520.         if (strres > 0) {
  521.             if (!Node1->Left) {
  522.                 Node1->Left = Node;
  523.                 return;
  524.             }
  525.             else {
  526.                 Node1 = Node1->Left;
  527.             }
  528.         }
  529.         else {
  530.             if (!strres) {
  531.                 // duplicate - must be adding a real ignore
  532.                 Node1->ReallyIgnore = TRUE;
  533.                 return;
  534.             }
  535.             else {
  536.                 if (!Node1->Right) {
  537.                     Node1->Right = Node;
  538.                     return;
  539.                 }
  540.                 else {
  541.                     Node1 = Node1->Right;
  542.                 }
  543.             }
  544.         }
  545.     }
  546. }
  547.  
  548. #ifdef MPINDEXPRINT
  549. #define TEMPLATE "TO/A,MERGE/K,IGNORE/K,MAXNODE/K/N,NODE/S,FROM/M,PRINT/S"
  550. #else
  551. #define TEMPLATE "TO/A,MERGE/K,IGNORE/K,MAXNODE/K/N,NODE/S,FROM/M"
  552. #endif
  553. #define OPT_TO            0
  554. #define OPT_MERGE        1
  555. #define OPT_IGNORE    2
  556. #define OPT_MAX        3
  557. #define OPT_NODE        4
  558. #define OPT_FROM        5
  559.  
  560. #ifdef MPINDEXPRINT
  561. #define OPT_PRINT        6
  562. #define OPT_COUNT        7
  563. #else
  564. #define OPT_COUNT        6
  565. #endif
  566.  
  567. static char Balance[32]="PHXDLT1BFJNRVZ3ACEGIKMOQSUWY024";
  568. //                       1234567890123456789012345678901
  569. //ABCDEFGHIJKLMNOPQRSTUVWXYZ01234"
  570. //               X
  571. //       X               X
  572. //   X       X       X       X
  573. // X   X   X   X   X   X   X   X
  574. //X X X X X X X X X X X X X X X X
  575.          
  576. int
  577. main(int argc, char **argv) {
  578.     long opts[OPT_COUNT] = {
  579.         0
  580.     };
  581.     FILE *in,*out;
  582.     char *p,*p1,*p2;
  583.     struct MyNode *MyNode,*Node1;
  584.     struct Word *Word;
  585.     char buffer[257];
  586.     char bbuf[2];
  587.     int i, resx=0;
  588.     int merged=0;
  589.     int seq;
  590.     char *t;
  591.     char *file;
  592.     if (!(rdargs = ReadArgs((char *)TEMPLATE, opts, NULL))) {
  593.         PrintFault(IoErr(), NULL);
  594.         return 10;
  595.     }
  596.     Chain = CreatePool(MEMF_CLEAR,PUDDLE,THRESH);
  597.     if (!Chain) {
  598.         printf("Error allocating memory pool\n");
  599.         FreeArgs(rdargs);
  600.         exit(10);
  601.     }
  602.     // Try and balance trees
  603.     bbuf[1]=0;
  604.     for (i=0; i<31; ++i) {
  605.         bbuf[0]=Balance[i];
  606.         AddWord(bbuf);
  607.         MyNode = Mycalloc(sizeof(struct MyNode));
  608.         MyNode->Name = bbuf;
  609.         AddNode(MyNode);
  610.         AddIgnore(bbuf,FALSE);
  611.     }
  612.     if (out=fopen((char *)opts[OPT_TO],"w")) {
  613.         if (opts[OPT_IGNORE]) {
  614.             if (in = fopen((char *)(opts[OPT_IGNORE]),"r")) {
  615.                 p = fgets(buffer,256,in);
  616.                 while (p) {
  617.                     buffer[strlen(buffer)-1] = 0;
  618.                     p = fgets(buffer,256,in);
  619.                     AddIgnore(p,TRUE);
  620.                 }
  621.                 fclose(in);
  622.             }
  623.             else {
  624.                 printf("Error opening %s\n",(char*)(opts[OPT_IGNORE]));
  625.                 resx=10;
  626.             }
  627.         }
  628.         if (opts[OPT_MERGE]) {
  629.             if (in=fopen((char*)(opts[OPT_MERGE]),"r")) {
  630.                 p = fgets(buffer,256,in);
  631.                 while (p) {
  632.                     while (p && (buffer[0] != '!')) {
  633.                         buffer[strlen(buffer)-1] = 0;
  634.                         if ('+' == buffer[0]) {
  635.                             file = Mystrdup(&(buffer[1]));
  636.                             fprintf(out,"+%s\n",file);
  637.                             ++merged;
  638.                         }
  639.                         else {
  640.                             seq = 0;
  641.                             t = buffer;
  642.                             while ('+' != *t) {
  643.                                 seq *= 10;
  644.                                 seq += (*t++ -'0');
  645.                             }
  646.                             ++t;
  647.                             MyNode = Mycalloc(sizeof(struct MyNode));
  648.                             MyNode->Name = Mystrdup(t);
  649.                             MyNode->seq = seq;
  650.                             p = fgets(buffer,256,in);
  651.                             buffer[strlen(buffer)-1] = 0;
  652.                             MyNode->Title=Mystrdup(p);
  653.                             AddNode(MyNode);
  654.                         }
  655.                         p = fgets(buffer,256,in);
  656.                     }
  657.                     NodeCount = 0;
  658.                     CountNodes(TopNode);
  659.                     while (p) {
  660.                         buffer[strlen(buffer)-1] = 0;
  661.                         if ('!' == buffer[0]) {
  662.                             Word = AddWord(&(buffer[1]));
  663.                         }
  664.                         else {
  665.                             seq = 0;
  666.                             t = buffer;
  667.                             while (*t) {
  668.                                 seq *= 10;
  669.                                 seq += (*t++ -'0');
  670.                             }
  671.                             Node1 = FindNode(TopNode,seq);
  672.                             LinkNodeWord(Node1,Word);
  673.                         }
  674.                         p = fgets(buffer,256,in);
  675.                     }
  676.                 }
  677.                 fclose(in);
  678.             }
  679.             else {
  680.                 printf("Error opening %s\n",(char*)(opts[OPT_MERGE]));
  681.                 resx=10;
  682.             }
  683.         }
  684.         for (i=0; opts[OPT_FROM] && ((char**)(opts[OPT_FROM]))[i]; ++i) {
  685.             file = Mystrdup(((char**)(opts[OPT_FROM]))[i]);
  686.             if (in=fopen(file,"r")) {
  687.                 p = fgets(buffer,256,in);
  688.                 while (p) {
  689.                     while (p && strnicmp(p,"@node ",6)) {
  690.                         p = fgets(buffer,256,in);
  691.                     }
  692.                     if (p) {
  693.                         Strip(buffer);
  694.                         MyNode = Mycalloc(sizeof(struct MyNode));
  695.                         MyNode->seq = i+merged;
  696.                         p1 = &(buffer[6]);
  697.                         while ((*p1) && isspace(*p1)) {
  698.                             ++p1;
  699.                         }
  700.                         if (*p1) {
  701.                             if ('"' == *p1) {
  702.                                 ++p1;
  703.                             }
  704.                             p2 = p1;
  705.                             while ((*p2) && !isspace(*p2)) {
  706.                                 ++p2;
  707.                             }
  708.                             --p2;
  709.                             if ('"' != *p2) {
  710.                                 ++p2;
  711.                             }
  712.                             *p2 = 0;
  713. //                            printf("MyNode - %s",p1);
  714.                             MyNode->Name = Mystrdup(p1);
  715.                             if (stricmp(MyNode->Name,"index")) {
  716.                                 p = fgets(buffer,256,in);
  717.                                 while (p && ((Strip(buffer),('@' == *p)) ||
  718.                                                  isspace(*p) || ('\n' == *p))) {
  719.                                     p = fgets(buffer,256,in);
  720.                                 }
  721.                                 if (p) {
  722.                                     p[strlen(p) - 1] = 0;
  723. //                                    printf(" - %s\n",p);
  724.                                     if (opts[OPT_NODE]) {
  725.                                         MyNode->Title = Mystrdup(MyNode->Name);
  726.                                     }
  727.                                     else {
  728.                                         MyNode->Title = Mystrdup(p);
  729.                                     }
  730.                                     AddNode(MyNode);
  731.                                     while (p && strnicmp(p,"@endnode",8)) {
  732.                                         AddWords(MyNode,buffer);
  733.                                         if (p = fgets(buffer,256,in)) {
  734.                                             Strip(buffer);
  735.                                         }
  736.                                     }
  737.                                 }
  738.                             }
  739.                             else {
  740.                                 free(MyNode);
  741.                                 while (p && strnicmp(p,"@endnode",8)) {
  742.                                     p = fgets(buffer,256,in);
  743.                                 }
  744.                             }
  745.                         }
  746.                         p = fgets(buffer,256,in);
  747.                     }
  748.                 }
  749.                 fclose(in);
  750.             }
  751.             else {
  752.                 printf("Error opening %s\n",((char**)(opts[OPT_FROM]))[i]);
  753.                 resx=10;
  754.             }
  755.         }
  756.         NodeCount = 0;
  757.         CountNodes(TopNode);
  758. #ifdef MPINDEXPRINT
  759.         if (opts[OPT_PRINT]) {
  760.             PrintNode(TopNode);
  761.             PrintWord(TopWord);
  762.         }
  763. #endif
  764.         WriteFiles((char **)opts[OPT_FROM],out);
  765.         WriteNodes(TopNode,out);
  766.         WriteWords(TopWord,out,opts[OPT_MAX]?*((ULONG *)opts[OPT_MAX]):0);
  767.         fclose(out);
  768.     }
  769.     else {
  770.         printf("Error opening %s\n",(char *)opts[OPT_TO]);
  771.         resx = 10;
  772.     }
  773.     FreeArgs(rdargs);
  774.     DeletePool(Chain);
  775.     return resx;
  776. }
  777.